const express = require('express')
const expressWs = require('express-ws') // 引入 WebSocket 包
const path = require('path');
const app = express()

const jwt = require("jsonwebtoken")
const {
	expressjwt
} = require("express-jwt")

expressWs(app) // 将 WebSocket 服务混入 app，相当于为 app 添加 .ws 方法
app.use(express.urlencoded({
	extended: false
}));
app.use(express.json());

//IP地址
global.isProd = 0 //1线上0测试
global.nowIP = isProd ? "https://shsim.ctrlikun.com" : "http://127.0.0.1";
global.imageNowIP = isProd ? "https://imageserve.ctrlikun.com" : "http://127.0.0.1";
const port = 3000;
global.port = 3000;

//设置跨域访问  
// app.all('*', function(req, res, next) {
// 	res.header('Access-Control-Allow-Origin', "*");
// 	res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization");
// 	res.header("Access-Control-Allow-Headers",
// 		"x-requested-with,Cache-Control,Pragma,Content-Type,Token, Content-Type,authorization");
// 	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
// 	res.header("X-Powered-By", ' 3.2.1');
// 	res.header("Content-Type", "application/json;charset=utf-8");
// 	// console.log('请求的地址',req.url);
// 	next();
// });
// 设置CORS的中间件
const cors = require('cors');
const shsServerAllowedOrigins = ['http://ctrlikun.com', 'https://ctrlikun.com',
	'https://www.ctrlikun.com', 'http://www.ctrlikun.com',
	'http://www.ctrlikun.com/', 'http://ctrlikun.com/',
	"shsim.ctrlikun.com", "http://shsim.ctrlikun.com", "https://shsim.ctrlikun.com"
];
shsServerAllowedOrigins.push("http://127.0.0.1:8080", 'http://localhost:8080')
shsServerAllowedOrigins.push("http://192.168.31.78:8080")
app.use(cors({
	origin: function(origin, callback) {
		// 允许预检请求
		if (!origin || shsServerAllowedOrigins.indexOf(origin) !== -1) {
			callback(null, true);
		} else {
			callback(new Error('SHS--Not allowed by CORS'));
		}
	}, // 允许的源
	methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许的HTTP请求方法
	allowedHeaders: ['Content-Type', 'Authorization'], // 允许的HTTP请求头
	optionsSuccessStatus: 204 // 成功的HTTP响应状态码
}));
// app.use(express.static(path.join(__dirname, 'public/dist')));
app.use(express.static(path.join(__dirname, 'public')))

let {
	getdate,
	timeDifference,
	handledOnline
} = require("./utils/base.js")
let {
	upIntegral
} = require("./utils/operate")

const {
	WSclose,
	WSsendMessage,
	WSsendAll
} = require("./utils/ws/index.js")
global.getdate = getdate;
global.timeDifference = timeDifference;
// 积分
global.upIntegral = upIntegral;
global.userCount = 0;

//建群最大人数
global.MaximumNumberOfPeople = 200;

//用户总数
global.wsClients = {}
// 用户详细信息
global.wsClientUsers = {}
app.wsClients = wsClients;
//推送信息
global.WSclose = WSclose
global.WSsendMessage = WSsendMessage
global.WSsendAll = WSsendAll

//面对面建群
global.positionNumber = 2
global.faceToFaceList = {}
//单位毫秒 面对面建群失效时间 失效清空数据
global.OperationTemp = undefined;
global.faceToFaceFailureTime = 60000; //60秒后失效
// global.faceToFaceFailureTime = 1000 * 10;

//单位毫秒 执行速率
global.OperationRate = 10000;
//jwt
global.jwt = jwt;
global.secretKey = "shsim";
global.expiresIn = 3600000; //token有效时间 单位1/s 60*60秒后失效
/** type :-1:token失效, 0:无, 1:message, 2:relationship, 3:online, 4:好友同意添加, 5缘分建群(PC端),55面对面建群(移动端)
	 7信息发送状态 9刷新联系人列表 99定向刷新联系人列表[不改变其他数据，不增加请求 code:deletecontact删除联系人，code:exit退出群聊]
	  10心跳检测 11：发送图片信息,333:刷新用户websorket的连接token,33有用户修改信息 更新积分榜信息**/
let obj = {
	code: 200,
	message: "请检查网络设置",
	type: 0,
	data: {
		message: "",
	}
}
let {
	jwtVerify,
	WSjwtVerify
} = require("./utils/token.js")
// 验证ws token
global.WSjwtVerify = WSjwtVerify
// 验证api token
global.jwtVerify = jwtVerify


let user = require("./router/user");
let relationship = require("./router/relationshipUser.js");
let restMessage = require("./router/restMessage.js");
let faceToFace = require("./router/faceToFace");
let faceToFaceV2 = require("./router/faceToFaceV2.js");
let shsimconfig = require("./utils/config");
let shsgroup = require("./router/shsgroup/index.js");
let shsHobbyTag = require("./router/hobby/index.js");
let shsDict = require("./router/dict/index.js");
let shsState = require("./router/state/index.js");
let shsStateComments = require("./router/state/comments.js");
let shsFriend = require("./router/friend/index.js");
let sensitivewords = require("./router/SensitiveWord/index.js");

global.shsDB = require('./db/index.js');
global.wsonmessage = require("./utils/onmessage.js")
global.wsonmessageImage = require("./utils/onmessageImage.js")
global.wsonmessageV = require("./utils/message/onmessage.js")
global.wsonfacetoface = require("./utils/faceToFace.js")
global.OperationfaceToFaceTime = require("./utils/faceTofaceUtils.js");

global.wsonfacetofaceV2 = require("./utils/facetofaceV2/faceToFace.js")
global.OperationfaceToFaceTimeV2 = require("./utils/facetofaceV2/faceTofaceUtils.js");

global.handledOnline = handledOnline; //在线用户状态处理

//用户相关
app.use("/user", user)
//联系人相关
app.use("/relationship", relationship)
//信息相关
app.use("/rest", restMessage)
//面对面建群
app.use("/faceToFace", faceToFace)
//面对面建群
app.use("/faceToFaceV2", faceToFaceV2)
//群聊相关
app.use("/shsgroup", shsgroup);
//爱好标签
app.use("/hobby", shsHobbyTag);
//字典
app.use("/dict", shsDict);
//动态
app.use("/state", shsState);
//动态评论相关
app.use("/shsStateComments", shsStateComments);
//推荐好友
app.use('/friend', shsFriend);
//敏感词
app.use('/sensitivewords', sensitivewords);
//配置相关
app.use("/shsimconfig", shsimconfig)
app.get('/', function(req, res, next) {
	// 设置状态码为302，并设置Location头部来指定重定向的URL
	// res.statusCode = 302;
	// res.setHeader('Location', 'www.ctrlikun.com:8080');
	// res.send();
	let sql = "select * from dict where code='serverContent'";
	let message = "Hello World!";
	shsDB(sql).then(data => {
		if (data.length) {
			message = data[0].value
		}
		res.send(JSON.stringify(message))
	}).catch(err => {
		message = err.message;
		res.send(JSON.stringify(message))
	})
})

let userOnlineOK = []; //在线确认机制


/**
 * @param int string wid 用户ID
 * @param  string wname  用户name
 */
app.ws('/ws/:wid/:wname', (ws, req) => {
	if (!wsClients[req.params.wid]) {
		wsClients[req.params.wid] = []
	}
	// 将连接记录在连接池中
	ws.wname = req.params.wname;
	ws.ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;

	let obj = {
		code: 200,
		message: "连接成功",
		type: 0,
		data: {
			message: "连接成功",
		}
	}
	ws.send(JSON.stringify(obj))

	ws.on('message', function(data) {
		let tokenRes = {
			type: -1, //token问题
			code: 401,
			message: "token problem"
		}
		let Item = JSON.parse(data);
		if (Item.type == 1024) {
			//登录 传token
			ws.wtoken = Item.token
			jwt.verify(Item.token, secretKey, (error, data) => {
				if (error) {
					obj.message = "无效token"
				} else {
					ws.user = data;
					ws.shsImUserInfo = {
						fromId: data.fromId,
						fromName: data.fromName,
						fromUrl: data.fromUrl,
						token: Item.token
					}
					wsClients[req.params.wid].push(ws); //多点登录 token区分
				}
			});
			//过滤信息
			handledOnline(1, req.params.wid, req.params.wname, ws.wtoken, ws.ip);
		} else if (Item.type == 1022) {
			//更新用户信息
			ws.wtoken = Item.token
			jwt.verify(Item.token, secretKey, (error, data) => {
				if (error) {
					obj.message = "无效token"
				} else {
					ws.user = data;
					ws.shsImUserInfo = {
						fromId: data.fromId,
						fromName: data.fromName,
						fromUrl: data.fromUrl,
						token: Item.token
					}
				}
			});
		}
		Item = Object.assign(Item, ws.shsImUserInfo);
		delete Item.token
		if (Item.type === 1 || Item.type === 11) {
			// 信息业务
			// wsonmessage
			wsonmessageV(Item, ws.wtoken);
		} else if (Item.type === 10) {
			// 心跳检测
		} else if (Item.type === 5) {
			//面对面建群业务PC
			wsonfacetoface(Item)
		} else if (Item.type === 55) {
			//面对面建群业务-移动
			wsonfacetofaceV2(Item);
		} else if (Item.type === 555) {
			//test
			console.log("test业务", Item);
		} else if (Item.type == 1089) {
			let userId = Item.data.userId
			let obj = {
				code: 200,
				type: 1088, //1088在线确认机制
				message: "onlineOK",
				data: {}
			}
		}

	})
	ws.onerror = (err) => {
		console.log("ws错误", err);
	}
	ws.onclose = (data) => {
		try {
			if (req.params.wid && req.params.wname) {
				handledOnline(0, req.params.wid, req.params.wname, data.target.wtoken, data.target
					.ip); //发送信息
			}
		} catch (e) {
			console.log("连接关闭错误", e)
		}
	}


});
// setInterval(() => {
// 	// 定时打印连接池数量
// 	console.log('-----------------------------');
// 	console.log('websocket connection counts:')
// 	Object.keys(wsClients).forEach(key => {
// 		console.log("ws客服端" + key, ':', wsClients[key].length);
// 		for (let i = 0; i < wsClients[key].length; i++) {
// 			console.log(wsClients[key][i].wtoken);
// 		}
// 	})
// 	// Object.keys(wsClientUsers).forEach(key => {
// 	// 	console.log("用户" + key + "username" + wsClientUsers[key].username);

// 	// })
// 	console.log('-----------------------------');
// }, OperationRate)

//错误中间件
const error = require("./utils/error.js");
const shsDB = require('./db/index.js');

app.use(error);


app.listen(port, () => {
	console.log(`express server listen at ${nowIP}:${port}`)
	console.log(`express server listen at ${nowIP}`)
})